package com.neuedu.corejava.ch13;

/**
 * 代码块锁只锁定特定代码块；方法锁是控制整个对象，会对所有线程起作用
 * @author myh
 * @version 2019年8月15日上午10:24:25
 *
 */
public class ThreadLocked {
	//只要是Object类或其他子类都可以做锁
	private static final Object LOCKED = new Object();
	//方法中可以有多把锁
	private static final Object LOCKED2 = new Object();
	private int count = 10;
	
	class ThreadInc implements Runnable {

		@Override
		public void run() {
			for (int i = 0; i < 20; i++) {
				Inc();
				try {
					Thread.sleep(100);
				} catch (InterruptedException e) {
				}
			}	
		}
	}

	class ThreadDec implements Runnable {
		@Override
		public void run() {
			for (int i = 0; i < 20; i++) {
				Dec();
				try {
					Thread.sleep(100);
				} catch (InterruptedException e) {
				}
			}	
		}
	}
	
	//使用了线程同步，解决了线程共享的问题，每个线程访问到的数据都是自己操作后的数据
	public   void Inc(){
		//代码块锁，使用一个对象锁定一个代码块，在代码块中控制对某个资源的共享
		synchronized(LOCKED){
			//对有线程安全的数据进行加锁，使用方法锁或代码块锁
			count++;
			System.out.println(Thread.currentThread().getId()+"-inc:"+count);
			//在同步快中调用其他锁的方法容易造成死锁
			Dec();
		}
	}
	//方法锁
	public synchronized  void Dec(){
		synchronized(LOCKED2){
			//对同一资源锁定必须使用同一把锁
			count--;
			System.out.println(Thread.currentThread().getId()+"-dec:"+count);
		}
	}

	public static void main(String[] args) {
		ThreadLocked testThread = new ThreadLocked();
		ThreadInc inc = testThread.new ThreadInc();
		ThreadDec dec = testThread.new ThreadDec();
		
		for (int i = 0; i < 2; i++) {
			Thread thread = new Thread(inc);
			Thread thread2 = new Thread(dec);
			thread.start();
			thread2.start();
		}
	}
}
